#include "Poco/Net/DNS.h"
#include "Poco/Net/HostEntry.h"
#include "Poco/Net/StreamSocket.h"
#include "Poco/Net/NetException.h"
#include "Poco/Net/SocketReactor.h"
#include "Poco/Net/SocketNotification.h"


#include "iostream"
#include "string"

class SocketAsyncHandler
{
public:
    SocketAsyncHandler(Poco::Net::StreamSocket & socket ):m_socket(socket)
    {

    }
    void handleRead(Poco::Net::ReadableNotification * sn)
    {
        char buf[100];
        int read = m_socket.receiveBytes( buf, 100 );
        
        std::cout<<"read:"<<read<<std::endl;
        sn->release();

        std::cout<<"beforeread:"<<std::endl;
        read = m_socket.receiveBytes( buf, 100 );
        std::cout<<"read:"<<read<<std::endl;
    }
    void handleWrite(Poco::Net::WritableNotification * wn)
    {
        int res;
        
        

        std::string head = "<?xml version='1.0' ?>";

        head += "<stream:stream to='jabber.org' xmlns='jabber:client'";

        head += " xmlns:stream='http://etherx.jabber.org/streams'  xml:lang='en' ";

        head += "version='1.0'>";

        res = m_socket.sendBytes(head.c_str(), head.length());
        if( res!=0)
        {
            wn->source().removeEventHandler(m_socket,
                Poco::Observer<SocketAsyncHandler,Poco::Net::WritableNotification>(*this,&SocketAsyncHandler::handleWrite));
            std::cout<<"write:";
        }

        wn->release();
        std::cout<<"write:"<<res<<"\n";
    }
protected:
private:
    Poco::Net::StreamSocket & m_socket;
};

int main()
{
    int res;
  //  const Poco::Net::HostEntry & he = Poco::Net::DNS::hostByName("jabber.org");

  //  std::cout<< he.addresses().size();

   // Poco::Net::StreamSocket skt;
    Poco::Net::StreamSocket skt(Poco::Net::IPAddress::IPv4);
     skt.setBlocking(false);
   // Poco::Net::SocketAddress sa("jabber.org","5222");
    Poco::Net::SocketAddress sa("localhost","800");
    

    Poco::Net::SocketReactor sr;
    sr.setTimeout(Poco::Timespan(1,0,0,0,0));

    SocketAsyncHandler sah(skt);

    Poco::Observer<SocketAsyncHandler, Poco::Net::ReadableNotification > obsr( sah, &SocketAsyncHandler::handleRead);

    sr.addEventHandler(skt, obsr );

    Poco::Observer<SocketAsyncHandler, Poco::Net::WritableNotification> obsw( sah, &SocketAsyncHandler::handleWrite);

    sr.addEventHandler(skt, obsw );

    try    {
        skt.connect(sa);
    }
    catch (Poco::Net::NetException* e)
    {
        std::cout<<e->displayText();
    }
    catch (...) {
        std::cout<<"haha";
    }
   
/*
    std::string head = "<?xml version='1.0' ?>";

    head += "<stream:stream to='jabber.org' xmlns='jabber:client' ";

    head += "xmlns:stream= 'http://etherx.jabber.org/streams'  xml:lang='en' ";

    head += "version='1.0'>";

    std::cout<<std::endl;
    std::cout<<head<<std::endl;

    res = skt.sendBytes(head.c_str(), head.length());

    std::cout<<"send res:"<<res<<std::endl;
  */
    sr.run();
    return 0;
}